﻿using B.S.RbacData.Infrastructure;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.EntityFrameworkCore;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using NLog.Web;
using System.Reflection;
using System.Text;

namespace B.S.RbacData.Read.API.Extensions
{

    /// <summary>
    /// 扩展方法
    /// </summary>
    public static class ServiceCollectionExtensions
    {


        public static WebApplicationBuilder Inject(this WebApplicationBuilder builder)
        {


            // Add services to the container.
            //连接数据库上下文
            builder.Services.AddDbContext<DataDbcontext>(x =>
            {

                x.UseSqlServer(builder.Configuration.GetConnectionString("conn"), action =>
                {

                    //配置EF core的重试策略
                    action.EnableRetryOnFailure(

                        maxRetryCount: 10,//最大重试次数
                        maxRetryDelay: TimeSpan.FromSeconds(60),//每次重试的时间间隔， 最大延迟
                        errorNumbersToAdd: null

                    );

                }).EnableSensitiveDataLogging();//启动敏感数据日志记录，便于调试，但在生产环境中应谨慎使用以避免泄露敏感信息

                //配置日志记录
                x.UseLoggerFactory(LoggerFactory.Create(
                    builder => builder.AddFilter(
                    category: DbLoggerCategory.Database.Name,//类别
                    level: LogLevel.Information//日志级别
                    ).AddConsole()));//控制台日志


            });
            //注册中介者
            builder.Services.AddMediatR(x => x.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly()));
            //注册automapper
            builder.Services.AddAutoMapper(typeof(AutoMapperProFiles));
            //注册仓储
            builder.Services.AddScoped(typeof(IBaseRepository<>), typeof(BaseRepository<>));
            //注册Nlog
            builder.Host.UseNLog();

            builder.Services.AddControllers();
            // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
            builder.Services.AddEndpointsApiExplorer();


            //配置Swagger
            builder.Services.AddSwaggerGen(o =>
            {

                // 显示 授权信息
                o.AddSecurityDefinition("Bearer", new Microsoft.OpenApi.Models.OpenApiSecurityScheme()
                {
                    Description = "添加JWT授权Token：Bearer Token值",
                    Name = "Authorization",
                    In = Microsoft.OpenApi.Models.ParameterLocation.Header,
                    Type = Microsoft.OpenApi.Models.SecuritySchemeType.ApiKey,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
                o.AddSecurityRequirement(new Microsoft.OpenApi.Models.OpenApiSecurityRequirement
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "Bearer"
                }
            },
            new string[]
            {

            }
        }
    });

                var pname = typeof(Program).Assembly.GetName().Name;

                var path = AppDomain.CurrentDomain.BaseDirectory + pname + ".xml";


                o.IncludeXmlComments(path, true);




            });

            //配置JWT

            // JWT Authentication 配置
            var jwtSettings = builder.Configuration.GetSection("JwtSettings");
            var secretKey = Encoding.UTF8.GetBytes(jwtSettings["SecretKey"]);

            builder.Services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.RequireHttpsMetadata = false;
                options.SaveToken = true;
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(secretKey),
                    ValidateIssuer = true,
                    ValidIssuer = jwtSettings["Issuer"],
                    ValidateAudience = true,
                    ValidAudience = jwtSettings["Audience"],
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero // 默认是5分钟，这里设置为0
                };
            });
            builder.Services.AddAuthorization();
            //配置上下文请求
            builder.Services.AddHttpContextAccessor();


            return builder;
        }

    }
}
